package _bye_util.logintrec;

/**
 * 
 * @author kagioglu
 */
public class Branch implements TreeNode
{
    private TreeNode left;
    private int separator;
    private TreeNode right;
    private int size;
    private int depth;
    
    public Branch( Leaf left, int separator, Leaf right ) {
        this.left = left;
        this.separator = separator;
        this.right = right;
        this.computeSize();
        this.computeDepth();
    }
    
    private void setLeft( TreeNode left )
    {
        this.left = left;
        this.computeSize();
        this.computeDepth();
    }
    
    private void setRight( TreeNode right )
    {
        this.right = right;
        this.computeSize();
        this.computeDepth();
    }
    
    public int size()
    {
        return this.size;
    }
    
    public int depth()
    {
        return this.depth;
    }
    
    public void computeSize()
    {
        this.size = this.left.size() + this.right.size();
    }
    
    private void computeDepth()
    {
        if ( this.left.depth() < this.right.depth() )
        {
            this.depth = this.right.depth() + 1;
        }
        else
        {
            this.depth = this.left.depth() + 1;
        }
    }
    
    public TreeNode newInt( int lowerBound, int upperBound, Ref newInt )
    {
        if ( lowerBound + this.left.size() < this.separator )
        {
            this.left = this.left.newInt( lowerBound, this.separator, newInt );
            return this.isLeftLong();
        }
        else
        {
            this.right = this.right.newInt( this.separator, upperBound, newInt );
            return this.isRightLong();
        }
    }
    
    public TreeNode recycleInt( int value )
    {
        if ( value < this.separator )
        {
            this.left = this.left.recycleInt( value );
            if ( this.left == null )
            {
                return this.right;
            }
            else
            {
                return this.isRightLong();
            }
        }
        else
        {
            this.right = this.right.recycleInt( value );
            if ( this.right == null )
            {
                return this.left;
            }
            else
            {
                return this.isLeftLong();
            }
        }
    }
    
    private TreeNode isLeftLong()
    {
        if ( this.left.depth() - this.right.depth() > 1 )
        {
            return this.left.shortenLeft( this );
        }
        else
        {
            this.computeSize();
            this.computeDepth();
            return this;
        }
    }
    
    private TreeNode isRightLong()
    {
        if ( this.right.depth() - this.left.depth() > 1 )
        {
            return this.right.shortenRight( this );
        }
        else
        {
            this.computeSize();
            this.computeDepth();
            return this;
        }
    }
    
    public Branch shortenLeft( Branch parent )
    {
        parent.setLeft( this.right );
        this.setRight( parent );
        return this;
    }
    
    public Branch shortenRight( Branch parent )
    {
        parent.setRight( this.left );
        this.setLeft( parent );
        return this;
    }
}
